Unit BCustomSessionUnit;

{$mode objfpc}{$H+}

Interface

Uses
  Classes, SysUtils, BRequestUnit;

Type

{ BCustomSessionClass }

 BCustomSessionClass = Class
  Private
    bID: Integer;
  Protected
    Procedure Release; Virtual; Abstract;
    //** Main method that set default parameteres for session
    Function Clone: TObject; Virtual;
  Public
    //** Identificator of Session stored at cookies
    Property ID: Integer Read bID;
    //** Main method for processing of request
    Procedure ProcessRequest(Const aRequest: BRequestClass); Virtual;
    Constructor Build(Const aID: Integer = -1); Virtual;
End;

//TODO: change for BPrimitiveThreadList
Type BSessionsThreadList = TThreadList;

Type

{ BSessionsManagerClass }

 BSessionsManagerClass = Class
  Private
    bPrototype: BCustomSessionClass;
    bSessions: BSessionsThreadList; Static;
    Function GetSession(Const aID: Integer): BCustomSessionClass;
  Protected
    Function AddSession: BCustomSessionClass; Virtual;
  Public
    Procedure ProcessRequest(Const aRequest: BRequestClass);
    Constructor Build(Const aProtoSession: BCustomSessionClass);
    Destructor Burn;
End;

Implementation

{ BCustomSessionClass }

Function BCustomSessionClass.Clone: TObject;
Begin
  Result := BCustomSessionClass.Build;
End;

Procedure BCustomSessionClass.ProcessRequest(Const aRequest: BRequestClass);
Begin

End;

Constructor BCustomSessionClass.Build(Const aID: Integer);
Begin
  If Not(aID = -1) Then bID := aID
  Else bID := Random(1000000);
End;

{ BSessionsManagerClass }

Procedure BSessionsManagerClass.ProcessRequest(Const aRequest: BRequestClass);
Var
  aSessionID: Integer;
  aSession: BCustomSessionClass;
Begin
  aSessionID := StrToIntDef(aRequest.Cookies.Values['SCGI_ID'], -1);
  aSession := GetSession(aSessionID);
  If aSession = nil Then
    Begin
      aSession := AddSession;
      aRequest.SetCookie('SCGI_ID=' + IntToStr(aSession.ID));
    End;
  aSession.ProcessRequest(aRequest);
End;

Function BSessionsManagerClass.AddSession: BCustomSessionClass;
Begin
  Result := BCustomSessionClass(bPrototype.Clone);
  bSessions.Add(Result);
End;

Function BSessionsManagerClass.GetSession(
  Const aID: Integer): BCustomSessionClass;
Var
  i: Integer;
Begin
  Result := nil;
  If aID = -1 Then Exit;
  With bSessions.LockList Do
    Try
      For i := 0 To Count - 1 Do
        If BCustomSessionClass(Items[i]).ID = aID Then
          Begin
            Result := BCustomSessionClass(Items[i]);
            Break;
          End;
    Finally
      bSessions.UnlockList;
    End;
End;

Constructor BSessionsManagerClass.Build(Const aProtoSession: BCustomSessionClass
  );
Begin
  bPrototype := aProtoSession;
End;

Destructor BSessionsManagerClass.Burn;
Begin

End;

Initialization
Begin
  BSessionsManagerClass.bSessions := BSessionsThreadList.Create;
End;

Finalization
Begin
  // Save here
  BSessionsManagerClass.bSessions.Free;
End;

End.
